#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>


//int main()
//{
//  printf("sherry");
//  sleep(4);
//
//  exit(12);
//}


//int main()
//{
//  printf("sherry");
//  sleep(4);
//
//  _exit(12);
//}


//int main()
//{
//  printf("sherry");
//  sleep(4);
//
//  exit(EXIT_SUCCESS);
//  //return 0;
//}


/*-------------------------------------------------*/
/*-------------wite---------------*/
//int main()
//{
//  pid_t id = fork();
//  if(id == 0)
//  {
//    int cnt = 5;
//    while(cnt)
//    {
//      printf("child:pid = %d, cnt = %d\n",getpid(), cnt);
//      cnt--;
//      sleep(1);
//    }
//    exit(12);
//  }
//
//  sleep(10);
//  printf("parent begin wait\n");
//  pid_t ret = wait(NULL);
//  if(ret == -1)
//  {
//    printf("parent wait failed\n");
//  }
//  else 
//  {
//    printf("parent wait success,ret = %d\n", ret);
//  }
//  sleep(5);
//  exit(0);
//}
//


/*----------------waitpid-------------*/ 
/*---pid---*/
//int main()
//{
//  pid_t id = fork();
//  if(id == 0)
//  {
//    int cnt = 5;
//    while(cnt)
//    {
//      printf("child:pid = %d, cnt = %d\n",getpid(), cnt);
//      cnt--;
//      sleep(1);
//    }
//    exit(12);
//  }
//
//  sleep(10);
//  printf("parent begin wait\n");
//  /*---等待指定id的子进程---*/ 
//  pid_t ret = waitpid(id, NULL, 0);
//  /*---等待任意一个子进程,等价于wait---*/ 
//  //pid_t ret = waitpid(-1, NULL, 0);
//  if(ret == -1)
//  {
//    printf("parent wait failed\n");
//  }
//  else 
//  {
//    printf("parent wait success,ret = %d\n", ret);
//  }
//  sleep(5);
//  exit(0);
//}


/*---status---*/
//int main()
//{
//  pid_t id = fork();
//  if(id == 0)
//  {
//    int cnt = 5;
//    while(cnt)
//    {
//      printf("child:pid = %d, cnt = %d\n",getpid(), cnt);
//      cnt--;
//      sleep(1);
//    }
//    /*---当子进程出现运行错误时，会给父进程发送一个退出信号---*/
//    // int a = 10;
//    // a /= 0;
//    exit(0);
//  }
//
//  sleep(10);
//  printf("parent begin wait!!!\n");
//  int status = 0;
//  pid_t ret = waitpid(id, &status, 0);
//  if(ret == -1)
//  {
//    printf("parent wait failed\n");
//  }
//  else 
//  {
//    /*---位操作获得exit_code 和 signal ---*/ 
//    // printf("parent wait success,ret = %d, status = %d, status_exit_code = %d, status_signal = %d\n", ret, status, (status>>8)&0xFF, (status)&0x7F);
//    /*---系统宏定义的标识符---*/
//    if(WIFEXITED(status)) // 表面系统正常运行代码结束，没用收到任何退出信号
//    {
//      // 获得对应的退出码
//      printf("exit_code:%d\n", WEXITSTATUS(status));
//    }
//    else 
//    {
//      printf("get a signal\n");
//    }
//  }
//  sleep(5);
//  exit(0);
//}


/*---options---*/
// 0:阻塞状态
//int main()
//{
//  pid_t id = fork();
//  if(id == 0)
//  {
//    int cnt = 5;
//    while(cnt)
//    {
//      printf("child:pid = %d, cnt = %d\n",getpid(), cnt);
//      cnt--;
//      sleep(1);
//    }
//    exit(0);
//  }
//
//  sleep(10);
//  printf("parent begin wait!!!\n");
//  int status = 0;
//  pid_t ret = waitpid(id, &status, 0);
//  if(ret == -1)
//  {
//    printf("parent wait failed\n");
//  }
//  else 
//  {
//    /*---系统宏定义的标识符---*/
//    if(WIFEXITED(status)) // 表面系统正常运行代码结束，没用收到任何退出信号
//    {
//      // 获得对应的退出码
//      printf("exit_code:%d\n", WEXITSTATUS(status));
//    }
//    else 
//    {
//      printf("get a signal\n");
//    }
//  }
//  sleep(5);
//  exit(0);
//}

// WNOHANG:非阻塞状态
//int main()
//{
//  pid_t id = fork();
//  if(id == 0)
//  {
//    int cnt = 10;
//    while(cnt)
//    {
//      printf("child:pid = %d, cnt = %d\n",getpid(), cnt);
//      cnt--;
//      sleep(1);
//    }
//    exit(0);
//  }
//
//  printf("parent begin wait!!!\n");
//  int status = 0;
//  while(1)
//  {
//    pid_t ret = waitpid(id, &status, WNOHANG);
//    if(ret == 0)
//    {
//      // 子进程没有退出，但是waitpid等待是成功的，需要父进程重复等待
//      printf("parent do anything\n");
//    }
//    else if(ret > 0)
//    {
//      // 子进程退出了，waitpid也成功了，获取到了对应的结果
//      printf("parent wait success,ret = %d, status = %d, status_exit_code = %d, status_signal = %d\n", ret, status, (status>>8)&0xFF, (status)&0x7F);
//      break;
//    }
//    else 
//    {
//      // 等待失败
//      printf("waitpid\n");
//      break;
//    }
//    sleep(1);
//  }
//  return 0;
//}


/*----------------------------------------------------------*/
/*---进程替换---*/
//int main()
//{
//  printf("I am a process, pid = %d\n", getpid());
//
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  return 0;
//}

/*---execl---*/ 
//int main()
//{
//  printf("I am a process, pid = %d\n", getpid());
//
//  sleep(5);
//  execl("/usr/bin/ls", "ls", "-a", "-l", NULL);
//
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  printf("sherry\n");
//  return 0;
//}


//int main()
//{
//  pid_t id = fork();
//  if(id == 0)
//  {
//    printf("I am a process, pid = %d\n", getpid());
//    
//    execl("/usr/bin/ls", "ls", "-l", "-a", NULL);
//
//    printf("sherry\n");
//    printf("sherry\n");
//    printf("sherry\n");
//    printf("sherry\n");
//    printf("sherry\n");
//    printf("sherry\n");
//
//    exit(1);
//  }
//  // parent
//  printf("I am father:pid = %d\n", getpid());
//  waitpid(id, NULL, 0);
//  printf("wait success!!\n");
//  return 0;
//}

/*---------work-----------*/
int main()
{
  pid_t id = fork();
  if(id == 0)
  {
    printf("i am child process\n");
    sleep(5);
    exit(0);
  }
  int status = 0;
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0)
  {
    if(WIFEXITED(status))
    {
      printf("exit_code:%d, coredump:%d, signal:%d\n", WEXITSTATUS(status), (status>>7)&0x80, status&0x7f);
    }
  }
  return 0;
}




